package com.wind.gateway.config;

import com.alibaba.cloud.nacos.ribbon.NacosRule;
import com.alibaba.cloud.sentinel.SentinelProperties;
import com.alibaba.cloud.sentinel.custom.SentinelDataSourceHandler;
import com.alibaba.cloud.sentinel.datasource.config.DataSourcePropertiesConfiguration;
import com.netflix.loadbalancer.IRule;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.core.env.Environment;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.util.pattern.PathPatternParser;
import reactor.core.publisher.Mono;

/**
 * ①获取nacos的权重
 * ②跨域配置
 * ③远程地址解析器
 * @author kinbug 
 */
@Configuration
@Slf4j
public class GatewayConfig {
	
	@Bean
	@Scope(value = "prototype")
	public IRule loadBalanceRule() {
		return new NacosRule();
	}
	
	/**
	 * -跨域支持配置
	 */
	@Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedMethod("*");
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
	
	/**
	 * -远程地址键解析器
	 */
	@Bean(value = "remoteAddrKeyResolver")
	public KeyResolver remoteAddrKeyResolver() {
		return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
	}

	@Bean
	public SentinelDataSourceHandler sentinelDataSourceHandler(DefaultListableBeanFactory beanFactory, SentinelProperties sentinelProperties, Environment env) {
		DataSourcePropertiesConfiguration dataSourcePropertiesConfiguration=sentinelProperties.getDatasource().get("ds1");
		MyNacosDataSourceProperties myNacosDataSourceProperties=new MyNacosDataSourceProperties();
		myNacosDataSourceProperties.setEnv(env);
		myNacosDataSourceProperties.setAccessKey(dataSourcePropertiesConfiguration.getNacos().getAccessKey());
		myNacosDataSourceProperties.setConverterClass(dataSourcePropertiesConfiguration.getNacos().getConverterClass());
		myNacosDataSourceProperties.setDataId(dataSourcePropertiesConfiguration.getNacos().getDataId());
		myNacosDataSourceProperties.setDataType(dataSourcePropertiesConfiguration.getNacos().getDataType());
		myNacosDataSourceProperties.setEndpoint(dataSourcePropertiesConfiguration.getNacos().getEndpoint());
		myNacosDataSourceProperties.setGroupId(dataSourcePropertiesConfiguration.getNacos().getGroupId());
		myNacosDataSourceProperties.setNamespace(dataSourcePropertiesConfiguration.getNacos().getNamespace());
		myNacosDataSourceProperties.setRuleType(dataSourcePropertiesConfiguration.getNacos().getRuleType());
		myNacosDataSourceProperties.setSecretKey(dataSourcePropertiesConfiguration.getNacos().getSecretKey());
		myNacosDataSourceProperties.setServerAddr(dataSourcePropertiesConfiguration.getNacos().getServerAddr());
		myNacosDataSourceProperties.setUsername(env.getProperty("spring.cloud.nacos.config.username"));
		myNacosDataSourceProperties.setPassword(env.getProperty("spring.cloud.nacos.config.password"));
		dataSourcePropertiesConfiguration.setNacos(myNacosDataSourceProperties);
		return new SentinelDataSourceHandler(beanFactory, sentinelProperties, env);
	}
}
